/*
 *  $Id: MainMenu.cs 1092 2010-05-25 10:54:44Z thenn.erannor $
 *	This file is a part of Ragima CCG.
 *	(C) 2008 Ragima development group.
 *
 *	Licensed under the terms of the GNU GPL License version 2.
 *
 */

using System;
using System.Collections.Generic;

using AgateLib.AudioLib;
using AgateLib.DisplayLib;
using AgateLib.InputLib;
using AgateLib.Geometry;

using Ragima.Menu;

namespace Ragima {
    public class MainMenu: OldScene {
        private static MainMenu _instance;
        public static MainMenu Instance {
            get { return _instance ?? (_instance = new MainMenu()); }
        }

        private const int MenuDistance = Constants.DisplayWidth;
        private const int MenuChangeFrames = 50;
        private const int MenuOffsetStep = MenuDistance / MenuChangeFrames;

        private UI.Sprite _sprite;

        private List<FlyingStar> _stars;
        private List<FlyingShroud> _shrouds;
        private ButtonGroup _current, _next;

        private ButtonGroup _main, _game;

        private MainMenu() {
            _sprite = Data.MenuButtons.GetSprite("buttons");
            _stars = new List<FlyingStar>();
            _shrouds = new List<FlyingShroud>();
            _main = new ButtonGroup(_sprite);
            _main.AddButton(ButtonNumber.StartGame, GoToGame);
            _main.AddButton(ButtonNumber.Profile, null);
            _main.AddButton(ButtonNumber.CardEditor, Application.StartDeckManager);
            _main.AddButton(ButtonNumber.Options, null);
            _main.AddButton(ButtonNumber.Credits, ParticleTestScene.Start);
            _main.AddButton(ButtonNumber.Quit, Application.Terminate);
            _game = new ButtonGroup(_sprite);
            _game.AddButton(ButtonNumber.Hotseat, Application.NewGame);
            _game.AddButton(ButtonNumber.NetGame, Application.NewNetGame);
            _game.AddButton(ButtonNumber.Return, ReturnToMain);
        }

        public override void InitializeScene() {
            base.InitializeScene();
            RegisterHotKey(KeyCode.Space, Application.NewGame);
            RegisterHotKey(KeyCode.Return, Application.NewNetGame);
            RegisterHotKey(KeyCode.E, Application.StartDeckManager);
            _stars.Clear();
            for (int i = 0; i < 20; i++) _stars.Add(new FlyingStar(StaticPointSource.CreateRandom()));
            for (int i = 0; i < 5; i++) _stars.Add(new FlyingStar(new SatellitePointSource(_stars[Randomizer.Global.Next(_stars.Count)])));
            _stars.Add(new FlyingStar(new MousePointSource()));
            _shrouds.Clear();
            for (int i = 0; i < 6; i++) _shrouds.Add(new FlyingShroud(false));
            _current = _main;
            _next = null;
            _current.Offset = 0;
            UpdateRegions();
            Play(Data.Musics.MainMenu, true);
        }

        public override void FinalizeScene() {
            base.FinalizeScene();
            Stop(Data.Musics.MainMenu);
        }

        public override void Draw() {
            Display.Clear();
            foreach (FlyingStar star in _stars) star.Draw();
            for (int i = 0; i < _shrouds.Count/2; i++) _shrouds[i].Draw();
            DrawRegions();
            for (int i = _shrouds.Count/2; i < _shrouds.Count; i++) _shrouds[i].Draw();
            DrawHint();
        }

        public override void Process() {
            if (EnabledControl)
                foreach (FlyingStar star in _stars) star.Process();
            foreach (FlyingShroud shroud in _shrouds) shroud.Process();
            ProcessRegions();
            ProcessHint();
        }

        protected override void UpdateRegions(List<Region> regions) {
            if (_current != null) _current.UpdateRegions(regions);
            if (_next != null) _next.UpdateRegions(regions);
        }

        private void ReturnToMain() {
            ChangeMenu(_main, false);
        }

        private void GoToGame() {
            ChangeMenu(_game, true);
        }

        private void ChangeMenu(ButtonGroup newMenu, bool dir) {
            DisableControl();
            Data.Sounds.Events.Play("menu.transition", dir ? 0 : 1);
            _next = newMenu;
            _next.Offset = dir ? MenuDistance : -MenuDistance;
            UpdateRegions();
            while (_next.Offset != 0) {
                NextFrame();
                int diff = Math.Min(MenuOffsetStep, Math.Abs(_next.Offset));
                if (dir) diff = -diff;
                _current.Offset += diff;
                _next.Offset += diff;
                foreach (FlyingStar star in _stars) star.SetOffset(diff);
            }
            _current = _next;
            _next = null;
            UpdateRegions();
            EnableControl();
        }
    }
}